package com.ruoyi.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.Message;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.SendInfo;
import com.ruoyi.common.core.domain.TreeEntity;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.tio.StartTioRunner;
import com.ruoyi.common.tio.TioServerConfig;
import com.ruoyi.common.tio.WsOnlineContext;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.MapUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.customer.common.DisCustomerBo;
import com.ruoyi.customer.common.DisCustomerRequestBo;
import com.ruoyi.customer.common.DisDeptBo;
import com.ruoyi.customer.common.DisUserBo;
import com.ruoyi.customer.common.DisVo;
import com.ruoyi.customer.domain.CommonInfo;
import com.ruoyi.customer.domain.Customer;
import com.ruoyi.customer.domain.CustomerChange;
import com.ruoyi.customer.domain.CustomerSource;
import com.ruoyi.customer.domain.MessageRecord;
import com.ruoyi.customer.domain.Remark;
import com.ruoyi.customer.domain.TCustomerTask;
import com.ruoyi.customer.domain.bo.CustomerBo;
import com.ruoyi.customer.domain.bo.CustomerPoolPullBo;
import com.ruoyi.customer.domain.bo.CustomerReturnPoolBo;
import com.ruoyi.customer.domain.bo.RecordBo;
import com.ruoyi.customer.domain.vo.CustomerVo;
import com.ruoyi.customer.domain.vo.MxInfoVo;
import com.ruoyi.customer.mapper.CustomerMapper;
import com.ruoyi.customer.mapper.MessageRecordMapper;
import com.ruoyi.customer.mapper.RemarkMapper;
import com.ruoyi.customer.mapper.TCustomerTaskMapper;
import com.ruoyi.customer.mapper.TotalComsterMapper;
import com.ruoyi.customer.recover.DisCustomerBoRecover;
import com.ruoyi.customer.service.CommonService;
import com.ruoyi.customer.service.DisCommonService;
import com.ruoyi.customer.service.ICustomerService;
import com.ruoyi.customerPool.domain.vo.CustomerPoolVo;
import com.ruoyi.disCustomer.domain.TCustomerDisRecord;
import com.ruoyi.disCustomer.mapper.TCustomerDisRecordMapper;
import com.ruoyi.enums.BusTypeEnum;
import com.ruoyi.enums.CompanyStatusEnum;
import com.ruoyi.enums.CurrentTypeEnum;
import com.ruoyi.enums.CustomerSort;
import com.ruoyi.enums.CustomerStatusEnum;
import com.ruoyi.recoverCustomer.domain.TRecoverCustomerLog;
import com.ruoyi.recoverCustomer.mapper.TRecoverCustomerLogMapper;
import com.ruoyi.returnCustomer.domain.TCustomerReturnRecord;
import com.ruoyi.returnCustomer.mapper.TCustomerReturnRecordMapper;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.utils.MessageSend;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.redisson.api.RMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.server.ServerTioConfig;
import org.tio.websocket.common.WsResponse;


/**
 * 客户信息Service业务层处理
 *
 * @author suntf
 * @date 2023-07-29
 */
@RequiredArgsConstructor
@Service
public class CustomerServiceImpl implements ICustomerService {

    private final CustomerMapper baseMapper;

    private final DisCommonService disCommonService;

    private final RemarkMapper remarkMapper;

    private final TCustomerTaskMapper tCustomerTaskMapper;

    private final StartTioRunner startTioRunner;

    private final ISysConfigService sysConfigService;

    private final ISysUserService sysUserService;

    private final TCustomerDisRecordMapper disRecordMapper;

    private final TCustomerReturnRecordMapper returnRecordMapper;

    private final TotalComsterMapper totalComsterMapper;

    private final ReentrantLock lock = new ReentrantLock();

    private final MessageSend messageSend;

    private final MessageRecordMapper messageRecordMapper;

    private final SysRoleMapper sysRoleMapper;

    private final TRecoverCustomerLogMapper recoverCustomerLogMapper;

    private final SysDeptMapper deptMapper;

    private final CommonService commonService;


    /**
     * 查询客户信息
     */
    @Override
    public CustomerVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询客户信息列表
     */
    @Override
    public TableDataInfo<CustomerVo> queryPageList(CustomerBo bo, PageQuery pageQuery) {
        // 参数为空
        if (!StringUtils.isNotBlank(bo.getCurrentType()) || !Arrays.asList("claim", "myCustomer", "pushCustomer")
                .contains(bo.getCurrentType())) {
            TableDataInfo<CustomerVo> rspData = new TableDataInfo<>();
            rspData.setCode(HttpStatus.HTTP_OK);
            rspData.setMsg("查询成功");
            rspData.setRows(Lists.newArrayList());
            rspData.setTotal(0);
            return rspData;
        }
        Page<CustomerVo> result = baseMapper.selectPageCustomerList(pageQuery.build(), this.buildQueryWrapper(bo));
        List<CustomerVo> customerVoList = result.getRecords().stream().peek(customerVo -> {
            // 处理手机号 脱敏
            String tel = customerVo.getTel();
            if (StringUtils.isNotBlank(tel) && Objects.equals(customerVo.getCompanyStatus(),
                    CompanyStatusEnum.DRL.getCode())) {
                String resultTel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
                customerVo.setTel(resultTel);
            }
        }).collect(Collectors.toList());
        return TableDataInfo.build(result.setRecords(customerVoList));
    }

    @Override
    public List<CustomerVo> queryInfoList(CustomerBo bo) {
        return baseMapper.selectCustomerList(this.buildQueryWrapper(bo));
    }

    /**
     * 查询客户信息列表
     */
    @Override
    public List<CustomerVo> queryList(CustomerBo bo) {
        QueryWrapper<Customer> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private QueryWrapper<Customer> buildQueryWrapper(CustomerBo bo) {
        Map<String, Object> params = bo.getParams();
        QueryWrapper<Customer> mwq = Wrappers.query();
        mwq.eq("tc.deleted", 0);
        mwq.apply("tc.distribute_dept_id = d.dept_id and tc.task_id = u.user_id");

        // 再分配客户 、我的客户 只允许创建人查看数据
        if (Arrays.asList("claim", "myCustomer").contains(bo.getCurrentType())) {
            mwq.eq("tc.task_id", LoginHelper.getUserId());
        }

        // 下推数据信息 is_push 1 已下推
        if (Objects.equals(bo.getCurrentType(), CurrentTypeEnum.PUSH_CUSTOMER.getCode())) {
            mwq.eq("tc.is_push", "1");
        }

        if (StringUtils.isNotBlank(bo.getStarType())) {
            mwq.eq("u.locked", 0);
            mwq.eq("tc.is_reviewe", -1);
            // 1星待签约7天
            mwq.apply(Objects.equals("one", bo.getStarType()),
                    "DATEDIFF(DATE_FORMAT(now(), '%Y-%m-%d'), DATE_FORMAT(ifnull(tc.last_remark_time,'2000-12-31 00:00:00'), '%Y-%m-%d')) >= 7 and tc.level = '1' and tc.customer_status = 3 ");
            // 3星1天
            mwq.apply(Objects.equals("three", bo.getStarType()),
                    "DATEDIFF(DATE_FORMAT(now(), '%Y-%m-%d'), DATE_FORMAT(ifnull(tc.last_remark_time,'2000-12-31 00:00:00'), '%Y-%m-%d')) >= 1 and tc.`level` = 3 and tc.customer_status = 3 ");
            // 2,4,5,6星3天
            mwq.apply(Objects.equals("other", bo.getStarType()),
                    "DATEDIFF(DATE_FORMAT(now(), '%Y-%m-%d'), DATE_FORMAT(ifnull(tc.last_remark_time,'2000-12-31 00:00:00'), '%Y-%m-%d')) >= 3 and tc.`level` in (2,4,5,6) and tc.customer_status = 3 ");
            // 新数据
            mwq.apply(Objects.equals("new", bo.getStarType()), "tc.customer_status = 1 and tc.is_new = 1");
        }

        // 再审件
        if (Objects.equals("1", bo.getRevieweFlag())) {
            mwq.ne("tc.is_reviewe", -1);
        } else if (Objects.equals("0", bo.getRevieweFlag())) {
            mwq.eq("tc.is_reviewe", -1);
        }

        mwq.eq(bo.getBusUserId() != null, "u.user_id", bo.getBusUserId());

        // 区分待认领和其他的数据
        mwq.eq(Objects.equals(CurrentTypeEnum.CLAIM.getCode(), bo.getCurrentType()), "tc.company_status",
                CompanyStatusEnum.DRL.getCode());

        mwq.eq(StringUtils.isNotBlank(bo.getCompanyStatus()), "tc.company_status", bo.getCompanyStatus());

        mwq.ne(Objects.equals(CurrentTypeEnum.MY_CUSTOMER.getCode(), bo.getCurrentType()), "tc.company_status",
                CompanyStatusEnum.DRL.getCode());

        mwq.ne(Objects.equals(CurrentTypeEnum.PUSH_CUSTOMER.getCode(), bo.getCurrentType()), "tc.company_status",
                CompanyStatusEnum.DRL.getCode());

        // 处理搜索条件
        mwq.like(StringUtils.isNotBlank(bo.getName()), "tc.name", bo.getName())
                .like(StringUtils.isNotBlank(bo.getTel()), "tc.tel", bo.getTel())
                .eq(StringUtils.isNotBlank(bo.getCustomerStatus()), "tc.customer_status", bo.getCustomerStatus())
                .eq(StringUtils.isNotBlank(bo.getLevel()), "tc.level", bo.getLevel())
                .eq(StringUtils.isNotBlank(bo.getLoanType()), "tc.loan_type", bo.getLoanType());
        // 未更新天数
        if (StringUtils.isNotBlank(bo.getNotUpdateDay())) {
            mwq.apply("TIMESTAMPDIFF(MINUTE, ifnull(tc.last_remark_time,'2000-12-31 00:00:00'), now()) >"
                    + bo.getNotUpdateDay() + " * 24 * 60");
        }
        // 1、进系统时间 2、实际申请时间
        if (StringUtils.isNotBlank(bo.getTimeType()) && StringUtils.isNotBlank(bo.getApplyTimeScope())) {
            String dateStr = "";
            // 今天、昨天、最近7天
            if (Arrays.asList("0", "1", "7").contains(bo.getApplyTimeScope())) {
                dateStr = DateUtils.getTimeBeforeDay(DateUtils.getNowDate(),
                        Integer.parseInt(bo.getApplyTimeScope()), "before");
            }
            // 本月
            if (Objects.equals("30", bo.getApplyTimeScope())) {
                dateStr = DateUtils.getFirstDayOfMonth();
            }
            if (StringUtils.isNotBlank(dateStr)) {
                if (Objects.equals("1", bo.getTimeType())) {
                    if (Arrays.asList("0", "1").contains(bo.getApplyTimeScope())) {
                        mwq.apply("tc.create_time = DATE_FORMAT('" + dateStr + "', '%Y-%m-%d 00:00:00' )");
                    } else {
                        mwq.apply("tc.create_time >= DATE_FORMAT('" + dateStr + "', '%Y-%m-%d 00:00:00' )");
                    }
                }
                if (Objects.equals("2", bo.getTimeType())) {
                    if (Arrays.asList("0", "1").contains(bo.getApplyTimeScope())) {
                        mwq.apply("tc.reality_apply_time = DATE_FORMAT('" + dateStr + "', '%Y-%m-%d 00:00:00' )");
                    } else {
                        mwq.apply("tc.reality_apply_time >= DATE_FORMAT('" + dateStr + "', '%Y-%m-%d 00:00:00' )");
                    }
                }
                mwq.apply(Objects.equals("2", bo.getTimeType()),
                        "tc.reality_apply_time >= DATE_FORMAT('" + dateStr + "', '%Y-%m-%d 00:00:00' )");
            }
            // 自定义时间特殊处理
            if (Objects.equals("99", bo.getApplyTimeScope())) {
                if (Objects.equals("1", bo.getTimeType())) {
                    mwq.ge(bo.getStartTime() != null, "tc.create_time", bo.getStartTime());
                    mwq.le(bo.getEndTime() != null, "tc.create_time", bo.getStartTime());
                } else {
                    mwq.ge(bo.getStartTime() != null, "tc.reality_apply_time", bo.getStartTime());
                    mwq.le(bo.getEndTime() != null, "tc.reality_apply_time", bo.getStartTime());
                }
            }
        }
        mwq.eq(StringUtils.isNotBlank(bo.getVip()), "tc.vip", bo.getVip());
        // 房产
        mwq.eq(StringUtils.isNotBlank(bo.getHouse()), "tc.house", bo.getHouse());
        // 公积金
        mwq.eq(StringUtils.isNotBlank(bo.getFund()), "tc.fund", bo.getFund());
        // 备注查询
        mwq.like(StringUtils.isNotBlank(bo.getBz()), "tc.bz", bo.getBz());
        mwq.like(StringUtils.isNotBlank(bo.getEducation()), "tc.education", bo.getEducation());
        // 来源
        mwq.like(StringUtils.isNotBlank(bo.getSource()), "tc.source", bo.getSource());
        // 贷款额度
        String applyMoney = bo.getApplyMoney();
        if (StringUtils.isNotBlank(applyMoney)) {
            String[] split = applyMoney.split("-");
            if (split.length == 2) {
                // 需处理数据格式
                mwq.gt(StringUtils.isNotBlank(applyMoney), "tc.apply_money", Long.valueOf(split[0]));
                mwq.lt(StringUtils.isNotBlank(applyMoney), "tc.apply_money", Long.valueOf(split[1]));
            }
        }

        // 渠道id
        String channelId = bo.getChannelId();
        if (StringUtils.isNotBlank(channelId)) {
            channelId = "," + channelId + ",";
            mwq.like("tc.channel_ids", channelId);
        }

        mwq.last(StringUtils.isNotBlank(bo.getSortInfo()),
                "order by tc." + CustomerSort.of(bo.getSortInfo()) + " " + bo.getSortRule());

        if (!StringUtils.isNotBlank(bo.getSortInfo())) {
            mwq.orderByDesc("tc.create_time");
        }
        return mwq;
    }

    /**
     * 新增客户信息
     */
    @Override
    @Transactional
    public Boolean insertByBo(CustomerBo bo) {
        Customer add = BeanUtil.toBean(bo, Customer.class);
        // 手机号去除空格
        if (StringUtils.isNotBlank(add.getTel())) {
            add.setTel(add.getTel().trim());
        }
        validEntityBeforeSave(add, "1");
        add.setDistributeDeptId(LoginHelper.getDeptId());
        // 新增客户备注信息 待调整 todo
        if (StringUtils.isNotBlank(bo.getBz())) {
            String remarkInfo =
                    bo.getBz() + "--" + LoginHelper.getLoginUser().getNickName() + "[" + DateUtils.parseDateToStr(
                            DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()) + "]";
            add.setBz(remarkInfo);
            add.setLastRemarkTime(new Date());
        }
        // 新增默认为新数据
        add.setCustomerStatus(CustomerStatusEnum.XSJ.getCode());
        add.setCompanyStatus(CompanyStatusEnum.DFP.getCode());
        add.setLastRemarkTime(DateUtils.getNowDate());
        // 处理
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            saveRemark(bo.getBz(), add.getId());
            totalCustomerUpdate(add.getId(), add.getTel());
            updateCustomerSource(add.getTel(), LoginHelper.getLoginUser().getNickName());
        }
        return flag;
    }

    /**
     * 更新总库、客户表
     */
    private void totalCustomerUpdate(Long id, String tel) {
        CommonInfo commonInfo = new CommonInfo();
        commonInfo.setId(id);
        commonInfo.setTel(tel);
        SpringUtils.context().publishEvent(commonInfo);
    }

    private void updateCustomerSource(String tel, String createBy) {
        CustomerSource customerSource = new CustomerSource();
        String source = "客户新增";
        customerSource.setSource(source);
        customerSource.setCreateBy(createBy);
        customerSource.setTel(tel);
        SpringUtils.context().publishEvent(customerSource);
    }

    /**
     * 保存用户备注
     *
     * @param content
     * @param id
     */
    public void saveRemark(String content, Long id) {
        // 单独保存缓存信息
        if (StringUtils.isNotBlank(content)) {
            // 接口未使用 暂不处理 TODO
            //String key = CacheConstants.CUSTOMER_BZ_KEY + id.toString();
            //RMap<Object, Object> rMap = RedisUtils.getClient().getMap(key);
            //String value = MapUtils.getStringValueByKey(rMap, key);
            //List<Remark> remarkList = JSONArray.parseArray(value, Remark.class);
            //if (!CollectionUtils.isEmpty(remarkList)) {
            //    // 查找之前的数据信息
            //    List<Remark> remarks = remarkMapper.selectList(
            //            new LambdaQueryWrapper<Remark>().eq(Remark::getCustomerId, id));
            //    if (!CollectionUtils.isEmpty(remarks)) {
            //        remarkList = remarks;
            //        rMap.put(key, JSONArray.from(remarkList));
            //    }
            //} else {
            //    remarkList = new ArrayList<>();
            //}
            LoginUser loginUser = LoginHelper.getLoginUser();
            Remark remark = new Remark();
            remark.setContent(content);
            remark.setCreateBy(Objects.nonNull(loginUser) ? loginUser.getNickName() : "");
            remark.setCustomerId(id);
            remark.setCreateTime(new Date());
            remark.setUserId(LoginHelper.getUserId());
            remarkMapper.insert(remark);
            //remarkList.add(remark);
            //rMap.put(key, JSONArray.from(remarkList));

        }
    }

    /**
     * 修改客户信息
     */
    @Override
    @Transactional
    public Boolean updateByBo(CustomerBo bo) {
        Customer update = BeanUtil.toBean(bo, Customer.class);
        validEntityBeforeSave(update, "2");

        saveRemark(bo.getBz(), bo.getId());
        CustomerVo oldCustomerInfo = Optional.ofNullable(baseMapper.selectVoById(bo.getId()))
                .orElseThrow(() -> new ServiceException("客户信息不存在"));
        if (StringUtils.isNotBlank(bo.getBz())) {
            StringBuilder stringBuilder = new StringBuilder();

            String remarkInfo =
                    bo.getBz() + "--" + LoginHelper.getLoginUser().getNickName() + "[" + DateUtils.parseDateToStr(
                            DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()) + "]";
            stringBuilder.append(remarkInfo);
            stringBuilder.append("<br/>");
            if (StringUtils.isNotBlank(bo.getRemark())) {
                stringBuilder.append(bo.getRemark());
            }
            update.setBz(stringBuilder.toString());
            update.setLastRemarkTime(new Date());

            // 我的客户里面填写了备注信息  就算跟进 更改客户状态为待跟进
            if (Objects.equals(bo.getCurrentType(), "myCustomer") && Objects.equals(bo.getCustomerStatus(),
                    CustomerStatusEnum.XSJ.getCode())) {
                //update.setCustomerStatus(CustomerStatusEnum.DGJ.getCode());
            }
        } else {
            update.setBz(bo.getRemark());
        }
        update.setRemark("");
        // 只要修改了就算认领 修改认领去除
        //if (Objects.equals(CurrentTypeEnum.CLAIM.getCode(), bo.getCurrentType())) {
        //    CustomerVo customerVo = baseMapper.selectVoById(update.getId());
        //    // 原：新数据-待认领 再分配界面 防止星级弹框 退回后 新数据-待分配  在填写备注 变成  新数据-已认领
        //    //Objects.equals(customerVo.getCustomerStatus(), CustomerStatusEnum.XSJ.getCode()) &&
        //    if (Objects.equals(
        //            customerVo.getCompanyStatus(), CompanyStatusEnum.DRL.getCode())) {
        //        update.setCompanyStatus(CompanyStatusEnum.YRL.getCode());
        //        update.setLastRemarkTime(new Date());
        //        update.setIsNew(0);
        //    }
        //}
        int i = baseMapper.updateById(update);
        if (i > 0) {
            String newOldJson = JsonUtils.toJsonString(update);
            String oldOldJson = JsonUtils.toJsonString(oldCustomerInfo);
            CustomerChange newCustomerChange = BeanUtil.toBean(update, CustomerChange.class);
            CustomerChange oldCustomerChange = BeanUtil.toBean(oldCustomerInfo, CustomerChange.class);
            Map<String, Object> map = new HashMap<>();
            map.put("customerId", bo.getId());
            map.put("tel", oldCustomerInfo.getTel());
            map.put("createId", LoginHelper.getUserId());
            map.put("createBy", LoginHelper.getLoginUser().getNickName());
            map.put("type", "customerInfoChange");
            // 异步执行
            commonService.customerChangeRecord(oldCustomerChange, oldOldJson, newCustomerChange, newOldJson, map, "2");
        }
        return i > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Customer entity, String type) {
        String tel = entity.getTel();
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tel", tel);
        queryWrapper.eq("deleted", "0");
        if ("2".equals(type)) {
            queryWrapper.ne("id", entity.getId());
        }
        // todo 还有一个判断是那个子公司的还是那个？
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ServiceException("该客户的手机号码已经存在!");
        }

    }

    /**
     * 批量删除客户信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 判断是否存在在审件信息
            for (Long id : ids) {
                CustomerVo customerVo = Optional.ofNullable(baseMapper.selectVoById(id))
                        .orElseThrow(() -> new ServiceException("客户信息不存在"));
                if (customerVo.getIsReviewe() != -1) {
                    throw new ServiceException("存在在审件记录不能进行操作");
                }
            }
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    @Override
    @Transactional
    public Boolean customerReturnPool(CustomerReturnPoolBo customerReturnPoolBo) {
        List<CustomerVo> customerVos = customerReturnPoolBo.getCustomerVos();
        if (!CollectionUtils.isEmpty(customerVos)) {
            List<Customer> customers = new ArrayList<>();
            for (CustomerVo customerBo : customerVos) {
                CustomerVo customerVo = Optional.ofNullable(baseMapper.selectVoById(customerBo.getId()))
                        .orElseThrow(() -> new BaseException("客户信息没有找到"));
                if (Objects.equals(customerVo.getDeleted(), "1")) {
                    throw new ServiceException("客户已经不存在");
                }
                if (customerVo.getIsReviewe() != -1) {
                    continue;
                }
                // 更改客户taskId
                Customer customer = new Customer();
                customer.setTaskId(-1L);
                customer.setId(customerBo.getId());
                // 退回到当前用户所属上级部门池
                //customer.setDistributeDeptId(customerBo.getParentDeptId());
                customer.setBackReason(customerReturnPoolBo.getBackReason());
                // 更改为新数据
                //customer.setCustomerStatus(CustomerStatusEnum.XSJ.getCode());
                //customer.setCompanyStatus(CompanyStatusEnum.DFP.getCode());
                // 更改为退回信息
                customer.setCompanyStatus(CompanyStatusEnum.YTH.getCode());
                customer.setLastRemarkTime(new Date());

                customer.setIsNew(0);
                customers.add(customer);

                // 记录退回信息
                TCustomerReturnRecord returnRecord = new TCustomerReturnRecord();
                returnRecord.setBusType(BusTypeEnum.BUS.getCode());
                returnRecord.setCustomerId(customerBo.getId());
                // 分配给哪个用户
                returnRecord.setReturnDeptId((customerBo.getParentDeptId()));
                returnRecord.setCustomerName(customerVo.getName());
                returnRecord.setTel(customerVo.getTel());
                returnRecord.setReturnReason(customerReturnPoolBo.getBackReason());
                saveReturnRecord(returnRecord);
            }
            if (!CollectionUtils.isEmpty(customers)) {
                baseMapper.updateBatchById(customers);
            }
        }
        return true;
    }


    private void saveReturnRecord(TCustomerReturnRecord returnRecord) {
        returnRecord.setOperatorId(LoginHelper.getUserId());
        returnRecord.setOperatorDeptId(LoginHelper.getDeptId());
        returnRecord.setOperatorName(LoginHelper.getLoginUser().getNickName());
        returnRecord.setCreateTime(DateUtils.getNowDate());
        returnRecordMapper.insert(returnRecord);
    }


    @Override
    @Transactional
    public String customerPoolPull(CustomerPoolPullBo customerPoolPullBo) {
        List<CustomerPoolVo> customerPoolVos = customerPoolPullBo.getCustomerPoolVos();
        if (!CollectionUtils.isEmpty(customerPoolVos)) {
            try {
                lock.lock();
                List<Customer> customerList = new ArrayList<>();
                for (CustomerPoolVo customerPoolVo : customerPoolVos) {
                    Long customerId = customerPoolVo.getId();

                    CustomerVo customerVo = Optional.ofNullable(baseMapper.selectVoById(customerId))
                            .orElseThrow(() -> new ServiceException("客户信息不存在"));
                    if (Objects.equals(customerVo.getDeleted(), "1")) {
                        continue;
                    }
                    if (customerVo.getIsReviewe() != -1) {
                        continue;
                    }
                    // 更新客户所属部门为当前用户部门
                    Customer customer = new Customer();
                    customer.setDistributeDeptId(LoginHelper.getDeptId());
                    customer.setId(customerId);
                    customer.setTaskId(LoginHelper.getUserId());
                    // 客户状态为 待跟进、 公司状态为 已认领
                    //customer.setCustomerStatus(CustomerStatusEnum.XSJ.getCode());
                    customer.setCompanyStatus(CompanyStatusEnum.YRL.getCode());
                    customer.setLastRemarkTime(new Date());
                    customer.setIsNew(1);
                    customer.setTel(customerPoolVo.getTel());
                    customer.setName(customerPoolVo.getName());
                    customerList.add(customer);
                }
                if (!CollectionUtils.isEmpty(customerList)) {
                    List<DisVo> custorList = customerList.stream().map(customer -> {
                        DisVo disVo = new DisVo();
                        disVo.setUserId(LoginHelper.getUserId());
                        disVo.setName(customer.getName());
                        disVo.setTel(customer.getTel());
                        disVo.setId(customer.getId());
                        return disVo;
                    }).collect(Collectors.toList());

                    Map<String, Object> map = disCommonService.userDataDeal(custorList);
                    List<DisVo> successList = (List<DisVo>) map.get("success");
                    List<DisVo> failList = (List<DisVo>) map.get("fail");

                    if (!CollectionUtils.isEmpty(successList)) {
                        if (!CollectionUtils.isEmpty(failList)) {
                            String collect = "," + failList.stream().map(it -> String.valueOf(it.getId()))
                                    .collect(Collectors.joining(",")) + ",";
                            customerList = customerList.stream().filter(it -> !collect.contains("," + it.getId() + ","))
                                    .collect(Collectors.toList());
                        }
                        if (!CollectionUtils.isEmpty(customerList)) {
                            baseMapper.updateBatchById(customerList);
                        }
                    }

                    if (!CollectionUtils.isEmpty(failList)) {
                        // 返回错误信息
                        return LoginHelper.getLoginUser().getNickName() + "客户总数已满300" + "<br/>" +
                                "未成功拉取客户：" + failList.stream().map(it -> {
                            return (StringUtils.isNotBlank(it.getName()) ? it.getName() : "") + "【" + it.getTel() + "】";
                        }).collect(Collectors.joining(","));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            } finally {
                lock.unlock();
            }
        }
        return "";
    }

    /**
     * 快过期的星级用户推送给客户 3星一天 ，2、4、5、6星三天一提醒， 1星(待签约状态) 七天提醒，上午11点，下午5点，提示用户，用户不点击确定，是不能操作页面的
     *
     * @param
     * @return void
     * @author: suntf
     * @date: 2023/8/18 11:45
     */
    @Override
    public void sendStarCustomerToUser() {
        //todo 判断是否设置全局日期，如果设置了，不用下面判断
        //获取ws中所有人员
        Set<String> wsRegisterUser = WsOnlineContext.getWSRegisterUser();

        // 保存消息记录
        MessageRecord messageRecord = new MessageRecord();
        messageRecord.setCreateBy("系统操作");
        messageRecord.setType(Constants.MESSAGE_STAR);
        wsRegisterUser.forEach(userId -> {
            // 判断用户是否有业务员角色，如果才发送通知，如果没有就不发送
            if (StringUtils.isNotBlank(userId)) {
                if (sysUserService.checkUserIsSendMsg(userId) > 0) {
                    ServerTioConfig serverTioConfig = startTioRunner.getAppStarter().getWsServerStarter()
                            .getServerTioConfig();
                    ChannelContext cc = WsOnlineContext.getChannelContextByUser(userId);
                    Map<String, String> customerStarInfo = getCustomerStarInfo(userId);
                    if (cc != null && !cc.isClosed && !CollectionUtils.isEmpty(customerStarInfo)) {
                        SendInfo sendInfo = new SendInfo();
                        sendInfo.setCode(Constants.MSG_MESSAGE);
                        Message msg = new Message();
                        msg.setContent(JSONObject.toJSONString(customerStarInfo));
                        msg.setTimestamp(System.currentTimeMillis());
                        msg.setType(Constants.MESSAGE_STAR);
                        sendInfo.setMessage(msg);
                        WsResponse wsResponse = null;
                        try {
                            wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo),
                                    TioServerConfig.CHARSET);
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                        Tio.sendToUser(serverTioConfig, userId, wsResponse);
                        // 保存推送记录
                        messageRecord.setUserIds(userId);
                        messageRecord.setContext(JSONObject.toJSONString(customerStarInfo));
                        messageRecordMapper.insert(messageRecord);

                    }
                }
            }
        });
    }

    /**
     * 快过期的星级用户推送给客户 3星一天 ，2、4、5、6星三天一提醒， 1星(待签约状态) 七天提醒，上午11点，下午5点，提示用户，用户不点击确定，是不能操作页面的
     *
     * @param
     * @param
     * @return void
     * @return void
     * @author: suntf
     * @date: 2023/8/15 20:35
     */
    @Override
    public void sendStarCustomerToUser(String userId) {

    }

    /**
     * type = 1  1星(待签约状态) 七天提醒 type = 2  2、4、5、6星三天一提醒， type = 3  3星 1天提醒 获取快过期用户信息
     *
     * @param userId
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author: suntf
     * @date: 2023/8/15 22:11
     */
    public List<Map<String, String>> getCustomerStarList(String userId) {
        // 先获取 1星的
        List<Map<String, String>> oneStarList = this.baseMapper.getUserStar("", userId, "one", "person", "");
        List<Map<String, String>> threeStarList = this.baseMapper.getUserStar("", userId, "three", "person", "");
        List<Map<String, String>> otherStarList = this.baseMapper.getUserStar("", userId, "other", "person", "");
        List<Map<String, String>> allStartList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(oneStarList)) {
            allStartList.addAll(oneStarList);
        }
        if (!CollectionUtils.isEmpty(otherStarList)) {
            allStartList.addAll(otherStarList);
        }
        if (!CollectionUtils.isEmpty(threeStarList)) {
            allStartList.addAll(threeStarList);
        }
        return allStartList;
    }


    /**
     * 查看提醒信息 根据类型查看
     *
     * @param lookType 查看类型，person 我的客户 在分配 reDis team 团队客户
     * @return java.util.Map<java.lang.String, java.lang.String>
     * @author: suntf
     * @date: 2023/8/20 11:11
     */
    public Map<String, String> getCustomerStar(String lookType) {
        String childrenId = LoginHelper.getLoginUser().getChildren();
        String userId = String.valueOf(LoginHelper.getUserId());

        // 查不到 部门为100 的不是当前用户的数据
        String deptId = String.valueOf(LoginHelper.getLoginUser().getDeptId());

        List<Map<String, String>> oneStarList = this.baseMapper.getUserListStarChange(deptId, childrenId, userId, "one",
                lookType);
        List<Map<String, String>> threeStarList = this.baseMapper.getUserListStarChange(deptId, childrenId, userId,
                "three",
                lookType);
        List<Map<String, String>> otherStarList = this.baseMapper.getUserListStarChange(deptId, childrenId, userId,
                "other",
                lookType);
        List<Map<String, String>> newList = this.baseMapper.getUserListStarChange(deptId, childrenId, userId, "new",
                lookType);

        Map<String, String> mp = new HashMap<>();
        if (!CollectionUtils.isEmpty(oneStarList)) {
            mp.put("one", String.valueOf(oneStarList.size()));
        } else {
            mp.put("one", "0");
        }
        if (!CollectionUtils.isEmpty(threeStarList)) {
            mp.put("three", String.valueOf(threeStarList.size()));
        } else {
            mp.put("three", "0");
        }
        if (!CollectionUtils.isEmpty(otherStarList)) {
            mp.put("other", String.valueOf(otherStarList.size()));
        } else {
            mp.put("other", "0");
        }
        if (!CollectionUtils.isEmpty(newList)) {
            mp.put("new", String.valueOf(newList.size()));
        } else {
            mp.put("new", "0");
        }
        return mp;
    }

    /**
     * 获取用户多少要回收用户信息
     *
     * @param userId
     * @return
     */
    public Map<String, String> getCustomerStarInfo(String userId) {

        StringBuffer stringBuffer = new StringBuffer();
        //SysUser sysUser = sysUserService.selectUserById(Long.valueOf(userId));
        String str = "";
        //if (sysUser != null) {
        //    str = "not EXISTS ( SELECT 1 from t_customer_remak cr where cr.del_flag = 0 and a.id = cr.customer_id and cr.create_by = '" + sysUser.getNickName() + "' and DATEDIFF(cr.create_time, now()) = 0 )";
        //}
        if (StringUtils.isNotBlank(str)) {
            // 新数据提醒
            List<Map<String, String>> myCustomerNewStarList = this.baseMapper.getUserStar("", userId, "newMyCustomer",
                    "person", str);
            if (!CollectionUtils.isEmpty(myCustomerNewStarList) && myCustomerNewStarList.size() > 0) {
                stringBuffer.append("新数据[我的客户]").append(myCustomerNewStarList.size()).append("位客户,");
            }
            // 新数据提醒
            List<Map<String, String>> newAgainCustomer = this.baseMapper.getUserStar("", userId, "newAgainCustomer",
                    "person", str);
            if (!CollectionUtils.isEmpty(newAgainCustomer) && newAgainCustomer.size() > 0) {
                stringBuffer.append("新数据[再分配客户]").append(newAgainCustomer.size()).append("位客户,");
            }
        }

        List<Map<String, String>> oneStarList = this.baseMapper.getUserStarSend("", userId, "one", "person", "");
        List<Map<String, String>> threeStarList = this.baseMapper.getUserStarSend("", userId, "three", "person", "");
        List<Map<String, String>> otherStarList = this.baseMapper.getUserStarSend("", userId, "other", "person", "");

        if (!CollectionUtils.isEmpty(oneStarList) && oneStarList.size() > 0) {
            stringBuffer.append("1星").append(oneStarList.size()).append("位客户,");
        }
        if (!CollectionUtils.isEmpty(threeStarList) && threeStarList.size() > 0) {
            stringBuffer.append("3星").append(threeStarList.size()).append("位客户,");
        }
        if (!CollectionUtils.isEmpty(otherStarList) && otherStarList.size() > 0) {
            stringBuffer.append("2星、4星、5星、6星有").append(otherStarList.size()).append("位客户");
        }
        Map<String, String> result = new HashMap<>();
        if (StringUtils.isNotBlank(stringBuffer.toString())) {
            result.put("info", "您有" + stringBuffer.toString() + "将被收回,请及时处理!");
        }
        return result;

    }

    @Override
    public R setVip(Long customerId, int type) {
        LambdaQueryWrapper<Customer> c = new LambdaQueryWrapper<>();
        c.eq(Customer::getVip, 1 - type).eq(Customer::getId, customerId);
        Customer customer = new Customer();
        customer.setId(customerId);
        customer.setVip(String.valueOf(type));
        int i = baseMapper.update(customer, c);
        if (i == 0) {
            return R.fail("操作失败,请重试!");
        }
        String key = String.format(Constants.VIP_USER, LoginHelper.getUserId());
        if (type == 1) {
            // 验证是否已经到达上线
            long value = RedisUtils.getAtomicValue(key);
            String s = sysConfigService.selectConfigByKey(Constants.MAX_VIP_NUMBER);
            if (value >= Long.parseLong(s)) {
                return R.fail("设置vip用户数量已达上线" + s + "人");
            }
            RedisUtils.incrAtomicValue(key);
        } else {
            RedisUtils.decrAtomicValue(key);
        }
        return R.ok();
    }

    @Override
    public R invite(Long customerId) {
        checkIsReview(customerId);
        Customer customer = new Customer();
        customer.setId(customerId);
        customer.setCustomerStatus(CustomerStatusEnum.DQY.getCode());
        baseMapper.updateById(customer);
        return R.ok();
    }

    private CustomerVo checkIsReview(Long customerId) {
        CustomerVo customerVo = Optional.ofNullable(baseMapper.selectVoById(customerId))
                .orElseThrow(() -> new BaseException("客户信息没有找到"));
        if (customerVo.getIsReviewe() != -1) {
            throw new ServiceException("存在再审件记录");
        }
        return customerVo;
    }

    @Override
    public R upDoor(Long customerId) {
        checkIsReview(customerId);
        Customer customer = new Customer();
        customer.setId(customerId);
        customer.setCustomerStatus(CustomerStatusEnum.YSM.getCode());
        baseMapper.updateById(customer);
        return R.ok();
    }

    private List<CustomerVo> check(List<Long> customerIds) {
        List<CustomerVo> customers = Lists.newArrayList();
        QueryWrapper<Customer> query = Wrappers.query();
        query.eq("deleted", "0");
        query.in("id", customerIds);
        query.select("id, name, tel, distribute_dept_id, is_reviewe, task_id");
        List<CustomerVo> voList = baseMapper.selectVoList(query);
        if (!CollectionUtils.isEmpty(voList)) {
            for (CustomerVo customerVo : voList) {
                if (customerVo.getIsReviewe() != -1 || Objects.equals(customerVo.getIsPush(), "1")) {
                } else {
                    customers.add(customerVo);
                }
            }
        }
        return customers;
    }

    @Override
    @Transactional
    public R pushCustomer(Long[] customerIds) {
        List<Customer> customers = Lists.newArrayList();
        List<Long> cutList = Lists.newArrayList();
        cutList.addAll(Arrays.asList(customerIds));
        List<CustomerVo> customerVos = check(cutList);
        // 记录下推消息
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(LoginHelper.getLoginUser().getNickName());
        stringBuilder.append("下推了客户：");
        for (CustomerVo customerVo : customerVos) {
            Customer customer = new Customer();
            customer.setId(customerVo.getId());
            customer.setIsPush("1");
            customer.setLastRemarkTime(DateUtils.getNowDate());
            customers.add(customer);

            // 保存下推记录
            TCustomerDisRecord disRecord = new TCustomerDisRecord();
            disRecord.setBusType(BusTypeEnum.PUSH.getCode());
            disRecord.setCustomerId(customerVo.getId());
            disRecord.setDisName(LoginHelper.getLoginUser().getNickName());
            // 分配给哪个部门
            disRecord.setDisDeptId(LoginHelper.getDeptId());
            disRecord.setCustomerName(customerVo.getName());
            // 记录分配记录
            disRecord(disRecord);
            stringBuilder.append("（" + customerVo.getName() + "--" + customerVo.getTel() + "）；");
        }
        if (!CollectionUtils.isEmpty(customers)) {
            baseMapper.updateBatchById(customers);
        }

        Map<String, String> map = new HashMap<>();
        map.put("info", stringBuilder.toString());
        List<SysUser> sysUsers = sysRoleMapper.selectSysUserRoleKey("dcl-customer");
        if (!CollectionUtils.isEmpty(sysUsers)) {
            List<String> collect = sysUsers.stream().map(SysUser::getUserId).map(String::valueOf)
                    .collect(Collectors.toList());
            messageSend.sendNotice(Constants.MESSAGE_PUSH, JSONObject.toJSONString(map), collect,
                    LoginHelper.getLoginUser().getNickName());
        }
        return R.ok();
    }

    /**
     * 分配
     *
     * @param pushDisBo
     * @return
     */
    @Override
    @Transactional
    public R pushDis(DisCustomerRequestBo pushDisBo) {
        List<DisCustomerBo> customerBos = disCommonService.checkDataUser(pushDisBo, BusTypeEnum.PUSH_FP.getCode());
        List<DisVo> disVos = disCommonService.dataDealUser(customerBos, pushDisBo.getUserBos());

        //Map<String, Object> map = disCommonService.userDataDeal(disVos);
        //List<DisVo> successList = (List<DisVo>) map.get("success");
        disCommonService.disToUser(disVos, BusTypeEnum.PUSH_FP.getCode(), LoginHelper.getLoginUser().getNickName(),
                LoginHelper.getUserId(), LoginHelper.getDeptId());

        //disCommonService.sentInfo(Constants.DIS_MESSAGE, map);
        return R.ok();
    }

    @Override
    @Transactional
    public R pushReturn(CustomerReturnPoolBo customerReturnPoolBo) {
        List<CustomerVo> customerVos = customerReturnPoolBo.getCustomerVos();
        QueryWrapper<Customer> query = Wrappers.query();
        query.eq("deleted", "0");
        query.in("id", customerVos.stream().map(CustomerVo::getId).collect(Collectors.toList()));
        query.select("id, name, tel, distribute_dept_id, is_reviewe, task_id");
        List<CustomerVo> voList = baseMapper.selectVoList(query);
        if (!CollectionUtils.isEmpty(voList)) {
            for (CustomerVo customerVo : voList) {
                if (customerVo.getIsReviewe() != -1) {
                    List<CustomerVo> customerBoList = customerVos.stream()
                            .filter(it -> it.getId().equals(customerVo.getId()))
                            .collect(Collectors.toList());
                    for (CustomerVo disCustomerBo : customerBoList) {
                        customerVos.remove(disCustomerBo);
                    }
                }
            }
        }
        if (!CollectionUtils.isEmpty(customerVos)) {
            List<Customer> collect = customerVos.stream().map(it -> {
                Customer customer = new Customer();
                customer.setId(it.getId());
                customer.setIsPush("0");
                if (StringUtils.isNotBlank(it.getName())) {
                    customer.setName(it.getName());
                }
                if (it.getDistributeDeptId() != null) {
                    customer.setDistributeDeptId(it.getDistributeDeptId());
                }
                if (it.getTaskId() != null) {
                    customer.setTaskId(it.getTaskId());
                }
                customer.setLastRemarkTime(DateUtils.getNowDate());
                return customer;
            }).collect(Collectors.toList());
//            List<TCustomerReturnRecord> returnRecords = Lists.newArrayList();
            List<TCustomerDisRecord> disRecords = Lists.newArrayList();
            for (Customer customerBo : collect) {
                TCustomerDisRecord disRecord = new TCustomerDisRecord();
                disRecord.setBusType(BusTypeEnum.PUSH_RETURN.getCode());
                disRecord.setCustomerId(customerBo.getId());
                // 分配给哪个部门
                disRecord.setDisDeptId(customerBo.getDistributeDeptId());
                disRecord.setDisUserId(customerBo.getTaskId());
                disRecord.setDisName(customerBo.getName());
                disRecord.setTaskId(customerBo.getTaskId());
                disRecord.setCustomerName(customerBo.getName());
                // 记录分配记录
                disRecord.setOperateDisId(LoginHelper.getUserId());
                disRecord.setOperateDeptId(LoginHelper.getDeptId());
                disRecord.setOperateDisName(LoginHelper.getLoginUser().getNickName());
                disRecord.setCreateTime(DateUtils.getNowDate());
                disRecord.setDisReason(customerReturnPoolBo.getBackReason());
                disRecords.add(disRecord);

                // 记录退回信息
//                TCustomerReturnRecord returnRecord = new TCustomerReturnRecord();
//                returnRecord.setBusType(BusTypeEnum.PUSH_RETURN.getCode());
//                returnRecord.setCustomerId(customerBo.getId());
//                // 分配给哪个用户
//                returnRecord.setReturnDeptId((customerBo.getDistributeDeptId()));
//                returnRecord.setCustomerName(customerBo.getName());
//                returnRecord.setReturnReason(customerReturnPoolBo.getBackReason());
//
//                returnRecord.setOperatorId(LoginHelper.getUserId());
//                returnRecord.setOperatorDeptId(LoginHelper.getDeptId());
//                returnRecord.setOperatorName(LoginHelper.getLoginUser().getNickName());
//                returnRecord.setCreateTime(DateUtils.getNowDate());
//                returnRecords.add(returnRecord);
            }
            baseMapper.updateBatchById(collect);
//            returnRecordMapper.insertBatch(returnRecords);
            disRecordMapper.insertBatch(disRecords);
        }
        // 记录退回信息
        return R.ok();
    }

    @Override
    public void newIntention() {
        List<Customer> customers = baseMapper.newIntentionToBus();
        if (CollectionUtils.isEmpty(customers)) {
            return;
        }
        // 保存当天操作的客户信息
        baseMapper.saveNewIntentionRecord();
        // 不校验业务员 300的数量
        customers.forEach(it -> {
            it.setLastRemarkTime(DateUtils.getNowDate());
            it.setIsNew(0);
            it.setCustomerStatus(CustomerStatusEnum.DQY.getCode());
            it.setCompanyStatus(CompanyStatusEnum.YRL.getCode());
        });
        baseMapper.updateBatchById(customers);
    }

    /**
     * 记录分配记录
     *
     * @param disRecord
     */
    private void disRecord(TCustomerDisRecord disRecord) {
        disRecord.setOperateDisId(LoginHelper.getUserId());
        disRecord.setOperateDeptId(LoginHelper.getDeptId());
        disRecord.setOperateDisName(LoginHelper.getLoginUser().getNickName());
        disRecord.setCreateTime(DateUtils.getNowDate());
        disRecordMapper.insert(disRecord);
    }

    @Override
    @Transactional
    public String customerRL(Long[] ids) {

        List<Customer> customerList = Lists.newArrayList();
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Customer::getId, ids);
        List<CustomerVo> customerVos = baseMapper.selectVoList(queryWrapper);
        if (!CollectionUtils.isEmpty(customerVos)) {
            for (CustomerVo customerVo : customerVos) {
                if (!Objects.equals(customerVo.getCompanyStatus(), CompanyStatusEnum.DRL.getCode())
                        || customerVo.getIsReviewe() != -1) {
                    continue;
                } else {
                    Customer customer = new Customer();
                    customer.setId(customerVo.getId());
                    customer.setCompanyStatus(CompanyStatusEnum.YRL.getCode());
                    customer.setLastRemarkTime(DateUtils.getNowDate());
                    customer.setIsNew(0);
                    customer.setName(customerVo.getName());
                    customer.setTel(customerVo.getTel());
                    customerList.add(customer);
                }
            }
        }
//        List<DisVo> custorList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(customerList)) {
            List<DisVo> custorList = customerList.stream().map(customer -> {
                DisVo disVo = new DisVo();
                disVo.setUserId(LoginHelper.getUserId());
                disVo.setName(customer.getName());
                disVo.setTel(customer.getTel());
                disVo.setId(customer.getId());
                return disVo;
            }).collect(Collectors.toList());

            Map<String, Object> map = disCommonService.userDataDeal(custorList);
            List<DisVo> successList = (List<DisVo>) map.get("success");
            List<DisVo> failList = (List<DisVo>) map.get("fail");

            if (!CollectionUtils.isEmpty(successList)) {
                if (!CollectionUtils.isEmpty(failList)) {
                    String collect = "," + failList.stream().map(it -> String.valueOf(it.getId()))
                            .collect(Collectors.joining(",")) + ",";
                    customerList = customerList.stream().filter(it -> !collect.contains("," + it.getId() + ","))
                            .collect(Collectors.toList());
                }
                if (!CollectionUtils.isEmpty(customerList)) {
                    baseMapper.updateBatchById(customerList);
                }
            }

            if (!CollectionUtils.isEmpty(failList)) {
                //disCommonService.sentInfo(Constants.DIS_MESSAGE, map);
                // 返回错误信息
                return LoginHelper.getLoginUser().getNickName() + "客户总数已满300" + "<br/>" +
                        "未成功认领客户：" + failList.stream().map(it -> {
                    return (StringUtils.isNotBlank(it.getName()) ? it.getName() : "") + "【" + it.getTel() + "】";
                }).collect(Collectors.joining(","));
            }
        }
        return "";
    }


    @Override
    @Transactional
    public void saveBz(RecordBo bo) {
        Customer customer = new Customer();

        if (!StringUtils.isNotBlank(bo.getBz())) {
            return;
        }
        // 填写了记录就代表不是新数据
        customer.setLastRemarkTime(DateUtils.getNowDate());

        saveRemark(bo.getBz(), bo.getId());

        StringBuilder stringBuilder = new StringBuilder();

        String remarkInfo =
                bo.getBz() + "--" + LoginHelper.getLoginUser().getNickName() + "[" + DateUtils.parseDateToStr(
                        DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate()) + "]";
        stringBuilder.append(remarkInfo);
        stringBuilder.append("<br/>");
        if (StringUtils.isNotBlank(bo.getRemark())) {
            stringBuilder.append(bo.getRemark());

        }

//        if (Objects.equals(CustomerStatusEnum.XSJ.getCode(), bo.getCustomerStatus())) {
//            customer.setCustomerStatus(CustomerStatusEnum.DGJ.getCode());
//        }
        customer.setBz(stringBuilder.toString());
        customer.setRemark("");
        customer.setId(bo.getId());

        customer.setIsNew(0);
        baseMapper.updateById(customer);
    }

    @Override
    public MxInfoVo getMxInfo(Long id) {
        CustomerVo customerVo = Optional.ofNullable(baseMapper.selectVoById(id))
                .orElseThrow(() -> new ServiceException("客户信息不存在"));
        MxInfoVo mxInfoVo = BeanUtil.toBean(customerVo, MxInfoVo.class);
        // 历史备注信息
        // 获取备注信息 从缓存里面
        //String key = CacheConstants.CUSTOMER_BZ_KEY + id;
        //RMap<Object, Object> rMap = RedisUtils.getClient().getMap(key);
        //String stringValueByKey = MapUtils.getStringValueByKey(rMap, key);
        //List<Remark> remarkList = JSONArray.parseArray(stringValueByKey, Remark.class);
        //if (!CollectionUtils.isEmpty(remarkList)) {
        //    String collect = remarkList.stream().sorted(Comparator.comparingLong(Remark::getId).reversed())
        //            .map(it -> {
        //                return "沟通人：" + it.getCreateBy() + "；时间：" + DateUtils.parseDateToStr(
        //                        DateUtils.YYYY_MM_DD_HH_MM_SS, it.getCreateTime()) + "；内容：" + it.getContent();
        //            }).collect(Collectors.joining("<br/>"));
        //    mxInfoVo.setLsbzRecord(collect);
        //}
        // 历史分配记录
        LambdaQueryWrapper<TCustomerTask> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.eq(TCustomerTask::getCustomerId, id);
        taskWrapper.orderByDesc(BaseEntity::getCreateTime);
        List<TCustomerTask> tCustomerTasks = tCustomerTaskMapper.selectList(taskWrapper);
        if (!CollectionUtils.isEmpty(tCustomerTasks)) {
            List<SysUser> sysUsers = sysUserService.selectUserList(new SysUser());
            String fpRecord = tCustomerTasks.stream().map(it -> {
                Optional<String> userInfo = sysUsers.stream()
                        .filter(item -> item.getUserId().equals(it.getManagerId()))
                        .map(SysUser::getNickName).findAny();
                String fpr = it.getCreateBy();
                String fpTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, it.getCreateTime());
                String toUser = "";
                if (userInfo.isPresent()) {
                    toUser = userInfo.get();
                }
                return "时间：" + fpTime + " " + fpr + "将" + mxInfoVo.getName() + "分配给了：" + toUser;
            }).collect(Collectors.joining("<br/>"));
            mxInfoVo.setLsfpRecord(fpRecord);
        }
        return mxInfoVo;
    }

    /**
     * 保存用户备注
     *
     * @param tCustomerTask
     * @param id
     */
    public void saveBackReason(TCustomerTask tCustomerTask, Long id) {
        // 单独保存缓存信息
        if (tCustomerTask != null) {
            String key = CacheConstants.CUSTOMER_RETURN_REASON_KEY + id.toString();
            RMap<Object, Object> rMap = RedisUtils.getClient().getMap(key);
            String value = MapUtils.getStringValueByKey(rMap, key);
            List<TCustomerTask> taskList = JSONArray.parseArray(value, TCustomerTask.class);
            if (taskList == null) {
                // 查找之前的数据信息
                List<TCustomerTask> reasons = tCustomerTaskMapper.selectList(
                        new LambdaQueryWrapper<TCustomerTask>().eq(TCustomerTask::getManagerId, id));
                if (!CollectionUtils.isEmpty(reasons)) {
                    taskList = reasons;
                } else {
                    taskList = new ArrayList<>();
                }
                rMap.put(key, JSONArray.from(taskList));
            } else {
                LoginUser loginUser = LoginHelper.getLoginUser();
                tCustomerTask.setUpdateBy(Objects.nonNull(loginUser) ? loginUser.getLoginId() : "");
                taskList.add(tCustomerTask);
                rMap.put(key, JSONArray.from(taskList));
            }
        }
    }

    /**
     * 回收客户信息
     *
     * @param
     * @return void
     * @author: suntf
     * @date: 2023/8/18 14:26
     */
    @Transactional
    public void recoverCustomer() {
        //todo 判断是否设置全局日期，如果设置了，不用下面判断

        int size = 500;
        List<Map<String, String>> customerStarList = getCustomerStarList("");
        String today = DateUtils.getDate();
        //分量操作
        if (!CollectionUtils.isEmpty(customerStarList) && customerStarList.size() > 0) {
            baseMapper.deleteRecoveryByDay(today);
            while (true) {
                if (customerStarList.size() > size) {
                    List<Map<String, String>> list = customerStarList.subList(0, size);
                    baseMapper.saveRecoveryCustomer(list, today);
                    list.clear();
                } else {
                    baseMapper.saveRecoveryCustomer(customerStarList, today);
                    break;
                }
            }
            // 删除锁定用户
            baseMapper.deleteRecoveryByLockedUser(today);

            //  跟改为查询配置  指定部门---指定人员

            baseMapper.updateCustomer(today, Constants.COMPANY_ID);
        }

    }


    @Override
    public void recoverDisCustomer(String type) {
        // 当前信息
        String today = DateUtils.getDate();
        LambdaQueryWrapper<TRecoverCustomerLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TRecoverCustomerLog::getOperatorDay, today);
        List<TRecoverCustomerLog> tRecoverCustomerLogs = recoverCustomerLogMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(tRecoverCustomerLogs)) {
            return;
        }
        List<DisCustomerRequestBo> disCustomerBoEndList = new ArrayList<>();
        // 待定
        // 查询部门信息
        LambdaQueryWrapper<SysDept> sysDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDeptLambdaQueryWrapper.eq(TreeEntity::getParentId, 100);
        sysDeptLambdaQueryWrapper.eq(SysDept::getIsDis, "0");
        List<SysDept> sysDeptList = deptMapper.selectDeptListTo(sysDeptLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(sysDeptList)) {
            return;
        }
        // 拿到用户 + 他可以分配的部门信息
        List<DisCustomerBoRecover> disCustomerBoList = tRecoverCustomerLogs.stream().map(it -> {
            DisCustomerBoRecover disCustomerBo = new DisCustomerBoRecover();
            disCustomerBo.setId(it.getCustomerId());
            disCustomerBo.setTel(it.getCustomerTel());
            disCustomerBo.setName(it.getCustomerName());
            List<SysDept> deptList = new ArrayList<>();
            sysDeptList.stream().forEach(item -> {
                if (!String.valueOf(item.getDeptId()).equals(it.getUserDept())) {
                    deptList.add(item);
                }
            });
            // 用于分组客户
            disCustomerBo.setDeptFlag(deptList.stream().map(its -> String.valueOf(its.getDeptId())).sorted().distinct()
                    .collect(Collectors.joining(",")));
            return disCustomerBo;
        }).collect(Collectors.toList());

        // 分组客户
        Set<String> deptType = new HashSet<>();
        disCustomerBoList.stream().forEach(itdis -> {
            if (deptType.contains(itdis.getDeptFlag())) {
                return;
            }
            deptType.add(itdis.getDeptFlag());
        });

        // 组装数据

        // 拿到部门分组  组合对于部门的所有客户
        for (String s : deptType) {
            List<String> deptInfo = Arrays.asList(s.split(","));
            DisCustomerRequestBo dis = new DisCustomerRequestBo();
            if (Objects.equals("pool", type)) {
                List<DisDeptBo> disDeptBoList = new ArrayList<>();
                deptInfo.forEach(itDept -> {
                    sysDeptList.stream().forEach(itDeptInfo -> {
                        if (itDept.equals(String.valueOf(itDeptInfo.getDeptId()))) {
                            DisDeptBo disDeptBo = new DisDeptBo();
                            disDeptBo.setDeptId(itDeptInfo.getDeptId());
                            disDeptBo.setDeptName(itDeptInfo.getDeptName());
                            disDeptBoList.add(disDeptBo);
                        }
                    });
                });
                if (CollectionUtils.isEmpty(disDeptBoList)) {
                    continue;
                }
                dis.setDeptBos(disDeptBoList);
            }

            if (Objects.equals("staff", type)) {
                String key = sysConfigService.selectConfigByKey(Constants.SALESMAN_ROLEKEY_TYPE);
                List<SysUser> sysUsers = baseMapper.deptByUser(key, deptInfo);
                // 返回用户信息
                if (CollectionUtils.isEmpty(sysUsers)) {
                    continue;
                }
                // 组装客户信息
                List<DisUserBo> disUserBoList = sysUsers.stream().map(it -> {
                    DisUserBo disUserBo = new DisUserBo();
                    disUserBo.setUserId(it.getUserId());
                    disUserBo.setNickName(it.getNickName());
                    disUserBo.setUserDeptId(it.getDeptId());
                    return disUserBo;
                }).collect(Collectors.toList());

                if (CollectionUtils.isEmpty(disUserBoList)) {
                    continue;
                }
                dis.setUserBos(disUserBoList);
            }

            // 组装客户
            List<DisCustomerBoRecover> collect = disCustomerBoList.stream()
                    .filter(itCustomer -> itCustomer.getDeptFlag().equals(s)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(collect)) {
                continue;
            }
            List<DisCustomerBo> disCustomerBos = BeanUtil.copyToList(collect, DisCustomerBo.class);
            if (CollectionUtils.isEmpty(disCustomerBos)) {
                continue;
            }
            dis.setDisCustomerBos(disCustomerBos);
            disCustomerBoEndList.add(dis);
            if (Objects.equals("pool", type)) {
                for (DisCustomerRequestBo disCustomerRequestBo : disCustomerBoEndList) {
                    coverDeptCustomer(disCustomerRequestBo, BusTypeEnum.RECOVER_DEPT_CUSTOMER.getCode());
                }
            }
            if (Objects.equals("staff", type)) {
                for (DisCustomerRequestBo disCustomerRequestBo : disCustomerBoEndList) {
                    coverUserCustomer(disCustomerRequestBo, BusTypeEnum.RECOVER_USER_CUSTOMER.getCode());
                }
            }
        }


    }


    private void coverDeptCustomer(DisCustomerRequestBo keyIssueBo, String operationType) {
        List<DisCustomerBo> disCustomerBos = disCommonService.checkDataDept(keyIssueBo,
                operationType);
        List<DisVo> disVos = disCommonService.dataDealDept(disCustomerBos, keyIssueBo.getDeptBos());
        disCommonService.disToDept(disVos, operationType, "管理员", 14L, 100L);
    }


    private void coverUserCustomer(DisCustomerRequestBo keyIssueBo, String operationType) {
        List<DisCustomerBo> disCustomerBos = disCommonService.checkDataUser(keyIssueBo,
                operationType);
        List<DisVo> disVos = disCommonService.dataDealUser(disCustomerBos, keyIssueBo.getUserBos());
        //Map<String, Object> map = disCommonService.userDataDeal(disVos);
        //List<DisVo> successList = (List<DisVo>) map.get("success");

        disCommonService.disToUser(disVos, operationType, "管理员", 14L, 100L);

        //disCommonService.sentInfo(Constants.DIS_MESSAGE, map);
    }


    public static void main(String[] args) {
        List<Remark> remarkList = com.alibaba.fastjson2.JSONArray.parseArray("", Remark.class);
        System.out.println(remarkList);
    }


    public Integer updateCustomerDeptByTask(SysUser sysUser){
        return baseMapper.updateCustomerDeptByTask(sysUser.getUserId(),sysUser.getDeptId());
    }
}
